package pl.vm.domain;

import java.io.Serializable;

import pl.vm.domain.exceptions.InvalidPlayerException;
import pl.vm.domain.exceptions.NotEnoughFoundsException;
import pl.vm.domain.exceptions.NotEnoughSpaceException;
import pl.vm.domain.exceptions.PlayerAlreadyExistException;
import pl.vm.domain.exceptions.PlayerNotExistsException;
import pl.vm.domain.exceptions.WrongPlayerPositionException;

public class VirtualTeam implements Serializable {

	private static final long serialVersionUID = -560504085819838080L;
	
	private String name;
	private Owner owner;
	/* amount of money available for the team */
	private int balance;
	private Player captain;
	private boolean teamRegistered = false;
	private Squad teamSquad = new Squad();

	public VirtualTeam(String name, Owner owner, int balance) {
		super();
		
		this.name = name;
		this.owner = owner;
		this.balance = balance;
	}

	public void registerTeam() {
			teamRegistered = true;
	}
		
	public boolean isTeamRegistered() {
		return teamRegistered;
	}
	
	public boolean isValid() {
		return teamSquad.validate();
	}
	
	public void buyPlayer(Player player) throws NotEnoughSpaceException, PlayerAlreadyExistException, NotEnoughFoundsException {
		if (balance < player.getWorth()) {
			throw new NotEnoughFoundsException("Player " + player + ", costs: " + player.getWorth() + ", and the balance is: " + balance);
		}
		getTeamSquad().addPlayer(player);
		balance -= player.getWorth();
	}

	public void sellPlayer(Player player) throws PlayerNotExistsException, InvalidPlayerException {
		getTeamSquad().removePlayer(player);
		balance += player.getWorth();
	}

	public Player getCaptain() {
		return captain;
	}
	
	public void setCaptain(Player player) throws PlayerNotExistsException {
		if (getTeamSquad().playerInSquad(player)) {
			this.captain = player;
		} else {
			throw new PlayerNotExistsException();
		}
	}
	
	/**
	 * Move player from reserve squad to main squad, and a player from main squad to reserve squad (switch places)
	 * If the players has different PlayerPosition then WrongPlayerPositionException is thrown. 
	 * If given player is not from main or reserve then InvalidPlayerException is thrown. 
	 * 
	 * @param main Player in main squad
	 * @param reserve Player in reserve squad
	 * @throws WrongPlayerPositionException thrown when PlayerPosition is incorrect
	 * @throws InvalidPlayerException 
	 * @throws PlayerNotExistsException 
	 * @throws NotEnoughSpaceException 
	 * 
	 * */
	public void switchPlayers(Player main, Player reserve) throws WrongPlayerPositionException, InvalidPlayerException, NotEnoughSpaceException, PlayerNotExistsException {
		getTeamSquad().switchPlayer(main, reserve);
	}
	
	/**
	 * Move player from reserve squad to main. If there is no room in main throws NoFreeSpaceInMainException.
	 * 
	 * @param reserve Player in reserve
	 * @throws PlayerNotExistsException 
	 * @throws InvalidPlayerException 
	 * @throws NotEnoughSpaceException 
	 */
	public void movePlayerToMain(Player reserve) throws NotEnoughSpaceException, InvalidPlayerException, PlayerNotExistsException {
		getTeamSquad().movePlayerToMain(reserve);
	}
	
	public void movePlayerToReserve(Player main) throws NotEnoughSpaceException, InvalidPlayerException, PlayerNotExistsException {
		getTeamSquad().movePlayerToReserve(main);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Owner getOwner() {
		return owner;
	}

	public void setOwner(Owner owner) {
		this.owner = owner;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		VirtualTeam other = (VirtualTeam) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	public Squad getTeamSquad() {
		return teamSquad;
	}
}
